/** @file

Copyright (c) 2006-2023, Kunlun BIOS, Kunlun Technology (Beijing) Co., Ltd.. All
Rights Reserved.

You may not reproduce, distribute, publish, display, perform, modify, adapt,
transmit, broadcast, present, recite, release, license or otherwise exploit
any part of this publication in any form, by any means, without the prior
written permission of Kunlun Technology (Beijing) Co., Ltd..

Module Name:


Abstract:


Revision History:

**/

#include <Uefi.h>
#include <Pi/PiBootMode.h>
#include <Pi/PiHob.h>
#include <Library/FlashLayoutLib.h>
#include <Library/HobLib.h>
#include <Library/DebugLib.h>
// #include <Pi/PiHob.h>
#include <Library/BaseMemoryLib.h>
#include <Library/MemoryAllocationLib.h>

EFI_GUID FlashLayoutHobGuid = EFI_FLASH_LAYOUT_HOB_GUID;

FLASH_SECTION* mFlashLayout = NULL;
UINTN          mSectionNum = 0;
EFI_STATUS
EFIAPI
GetFlashLaoutHobData(
)
{
  void* HobList;
  EFI_HOB_GUID_TYPE* Hob;

  HobList = GetHobList();
  if(HobList == NULL) return EFI_NOT_FOUND;
  Hob = GetNextGuidHob(&FlashLayoutHobGuid,HobList);
  if(!Hob)return EFI_NOT_FOUND;
  mSectionNum = (Hob->Header.HobLength - sizeof(EFI_HOB_GUID_TYPE))/sizeof(FLASH_SECTION);
  mFlashLayout = (FLASH_SECTION*)(Hob+1);
  return EFI_SUCCESS;
}

/**

  Obtain the specified FLASH_SECTION according to Tpye.

  @param Type               FlashSection Type.
  @param Section            Return FLASH_SECTION.

  @retval  EFI_SUCCESS      Successfully found the Section.
  @retval  EFI_NOTFOUND     Not found the Section.


**/
EFI_STATUS
EFIAPI
GetFlashSectionInfo(
    IN FLASH_SECTION_TYPE Type,
    OUT FLASH_SECTION* Section
)
{
  UINTN                          Index;
  EFI_STATUS                     Status;
  if((mFlashLayout == NULL)||(mSectionNum == 0)){
    Status = GetFlashLaoutHobData();
    DEBUG ((DEBUG_ERROR, "%a %d Status%r \n", __FUNCTION__, __LINE__,Status));
    if(EFI_ERROR(Status)) return EFI_NOT_FOUND;
  }
  if((Type<TYPE_COMMOM_START)||(Type>TYPE_END))
    return EFI_INVALID_PARAMETER;
  if((mSectionNum == 0)||(mFlashLayout == NULL))
    return EFI_NOT_FOUND;
  for ( Index = 0; Index < mSectionNum; Index++)
  {
    DEBUG ((DEBUG_ERROR, "%a %d mFlashLayout[Index].Type:%d  Type:%d \n", __FUNCTION__, __LINE__,mFlashLayout[Index].Type,Type));
    if(mFlashLayout[Index].Type == Type){
      CopyMem(Section,&mFlashLayout[Index],sizeof(FLASH_SECTION));
      return EFI_SUCCESS;
    }
  }
  return EFI_NOT_FOUND;
}
/**

  Get the FlashSection list.

  @param SectionList        Section List.
  @param SectionNum         Section Num.

  @retval  EFI_SUCCESS      Successfully found the Section List.
  @retval  EFI_NOTFOUND     Not found the Section.

**/
EFI_STATUS
EFIAPI
GetFlashLayoutInfo(
  OUT FLASH_SECTION** SectionList,
  UINTN* SectionNum
)
{
  EFI_STATUS                     Status;

  if((mFlashLayout == NULL)||(mSectionNum == 0)){
    Status = GetFlashLaoutHobData();
    DEBUG ((DEBUG_ERROR, "%a %d Status%r \n", __FUNCTION__, __LINE__,Status));
    if(EFI_ERROR(Status)) return EFI_NOT_FOUND;
  }
  if((SectionList == NULL)||(SectionNum == NULL))
    return EFI_INVALID_PARAMETER;
  if((mSectionNum == 0)||(mFlashLayout == NULL))
    return EFI_NOT_FOUND;
  // *SectionList = AllocateCopyPool(sizeof(FLASH_SECTION)*mSectionNum,(void*)mFlashLayout);
  *SectionList = mFlashLayout;
  *SectionNum = mSectionNum;
  return EFI_SUCCESS;
}



#if _FLASH_ROM_INFO_SUPPORT
EFI_GUID FlashRomInfoHobGuid = EFI_FLASH_ROM_INFO_HOB_GUID;

EFI_STATUS
EFIAPI
GetFlashRomInfoHobData(
OUT UINT32* FlashSizeInfo_Hob,
OUT UINT32* SectionSizeInfo_Hob
)
{
  void*                 OneHobList;
  EFI_HOB_GUID_TYPE*    OneHob;

  OneHobList = GetHobList();
  if(OneHobList == NULL)
  {
   return EFI_NOT_FOUND;
  }
  OneHob = GetNextGuidHob(&FlashRomInfoHobGuid,OneHobList);
  if(!OneHob){
  return EFI_NOT_FOUND;
  }

  *FlashSizeInfo_Hob = ((FLASH_ROM_INFO*)(OneHob+1))->RomSize;
  *SectionSizeInfo_Hob = ((FLASH_ROM_INFO*)(OneHob+1))->SectorSize;
  return EFI_SUCCESS;
}
#endif
